// Copyright (C) joyinter
// All rights reserved.
// 
// Author : Jiang Li
// Date   : 2004-6-23

#include "stdafx.h"
#include "button.h"
#include "tooltip.h"

//##ModelId=44CF17B902AF
CJoyButton::CJoyButton(void)
{
    m_state = BTN_NORMAL;
    m_pEventCtrl = NULL;
    m_pOnClick = NULL;

    m_checkedBtn = false;
    m_invertX   = false;
    m_invertY   = false;
    m_rotate    = 0.0f;

    m_skinArea  = true;

    m_hoverTime = 0;
    m_tipDelay  = 500;
    m_toolTip   = NULL;
}

//##ModelId=44CF17B902B1
CJoyButton::~CJoyButton(void)
{
}

//##ModelId=44CF17B902CF
void CJoyButton::FitImage()
{
    if(m_image == NULL)
    {
        return;
    }
    INT h = (INT)m_image->GetHeight();
    INT w = (INT)m_image->GetWidth()/4;

    SetArea(CRect(
        m_area.left,
        m_area.top,
        m_area.left + w,
        m_area.top + h));
}

//##ModelId=44CF17B902C1
void CJoyButton::Click()
{
    if(m_pEventCtrl != NULL)
    {
        (m_pEventCtrl->*m_pOnClick)(this);
    }
}

//##ModelId=44CF17B902B4
void CJoyButton::SetClickEvent(CJoyWnd* pCtrl, PClickEvent pOnClick)
{
    m_pEventCtrl    = pCtrl;
    m_pOnClick      = pOnClick;
}
#pragma push_macro("new")
#undef new

//##ModelId=44CF17B902C2
void CJoyButton::ArcClip()
{
    GraphicsPath path;
    path.AddEllipse(-1, -1, m_area.Width() + 1, m_area.Height() + 1);
    Region* clip = new Region(&path);

    SetClip(clip);
}

//##ModelId=44CF17B902C3
void CJoyButton::LeftArcClip()
{
    INT w = (INT)m_area.Width();
    INT h = (INT)m_area.Height();

    GraphicsPath path;
    path.AddEllipse(-1, -1, h + 1, h + 1);
    Region* clip = new Region(&path);
    clip->Union(Rect(h/2, 0, w-h/2, h));

    SetClip(clip);
}

//##ModelId=44CF17B902CE
void CJoyButton::RightArcClip()
{
    INT w = (INT)m_area.Width();
    INT h = (INT)m_area.Height();

    GraphicsPath path;

    path.AddEllipse(w-h-1, -1, h + 1, h + 1);
    Region* clip = new Region(&path);
    clip->Union(Rect(0, 0, w-h/2, h));

    SetClip(clip);
}

#pragma pop_macro("new")

//##ModelId=44CF17B902BF
void CJoyButton::SetImage(PCTSTR pszImage)
{
    m_image = JoyGetManager()->CreateImage(pszImage);
}

//##ModelId=44CF17B90272
void CJoyButton::CM_LoadSkin(CJoyXmlElement* pSkinElem)
{
    __super::CM_LoadSkin(pSkinElem);

    CJoyXmlAttribute* pImageAttrib = pSkinElem->FindAttribute("image");
    if(pImageAttrib != NULL)
    {
        if(!pImageAttrib->m_value.IsEmpty())
        {
            SetImage(pImageAttrib->m_value);
        }
    }

    m_checkedBtn = ("1" == pSkinElem->GetAttribute("checked_btn")->m_value);
    m_invertX = ("1" == pSkinElem->GetAttribute("invert_x")->m_value);
    m_invertY = ("1" == pSkinElem->GetAttribute("invert_y")->m_value);
}

//##ModelId=44CF17B90290
void CJoyButton::CM_Enabled(bool e)
{
    __super::CM_Enabled(e);

    if(m_enabled)
    {
        m_state = BTN_NORMAL;
    }
    else
    {
        m_state = BTN_DISABLE;
    }
}

//##ModelId=44CF17B90275
void CJoyButton::CM_MouseLeave()
{
    __super::CM_MouseLeave();
    if(!m_enabled)
    {
        return;
    }
    if(m_toolTip != NULL)
    {
        m_toolTip->HideTip();
    }
    m_state  = BTN_NORMAL;
    InvalidateCtrl();
}

//##ModelId=44CF17B90277
void CJoyButton::CM_MouseHover()
{
    __super::CM_MouseHover();
    if(!m_enabled)
    {
        return;
    }
    if(m_toolTip != NULL)
    {
        m_toolTip->SetTipText(m_tipText);
        m_toolTip->ShowTip(this);
    }
    m_hoverTime = GetTickCount();
    m_state  = BTN_HOVER;
    InvalidateCtrl();
}

//##ModelId=44CF17B90281
void CJoyButton::CM_Mouse(MouseMessage msg, const CPoint& pt)
{
    __super::CM_Mouse(msg, pt);

    if(!m_enabled)
    {
        return;
    }
    BUTTON_STATE btnState = m_state;
    switch(msg)
    {
    case MM_LeftDown:
        btnState  = BTN_DOWN;
        break;
    case MM_LeftUp:
        {
            btnState  = BTN_HOVER;
        }        
        break;
    case MM_LeftDouble:
        m_state = BTN_HOVER;
        Click();
        return;
    case MM_Move:
        if(m_toolTip != NULL)
        {
            //if(!m_toolTip->IsVisible())
            //{
            //    if(GetTickCount()-m_hoverTime > m_tipDelay)
            //    {
            //        m_toolTip->ShowTip(this);
            //    }
            //}
        }
        break;
    default:
        btnState = m_state;
        break;
    }
    if(m_state != btnState)
    {
        if(msg == MM_LeftUp)
        {
            if(m_state == BTN_DOWN)
            {
                m_state = btnState;
                Click();
            }
        }
        else
        {
            m_state = btnState;
        }
        InvalidateCtrl();
    }
}

//##ModelId=44CF17B90285
void CJoyButton::CM_Draw(Graphics& graph)
{
    if(m_image == NULL)
    {
        return;
    }
    int i = (int)m_state;

    INT h = (INT)m_image->GetHeight();
    INT w = (INT)m_image->GetWidth()/4;
    INT l = w*i;
    int t = 0;

    Rect dest(0, 0, w, h);

    if(m_invertX)
    {
        l += w-1;
        w = -w;
    }
    if(m_invertY)
    {
        t = h-1;
        h = -h;
    }

    if(m_rotate == 0.0f)
    {
        graph.DrawImage(m_image, dest, l, t, w, h, UnitPixel, NULL, NULL, NULL);
        return;
    }

    int aw = m_area.Width(), ah = m_area.Height();
    Matrix trans;
    graph.GetTransform(&trans);

    REAL tx = (REAL)aw / 2;
    REAL ty = (REAL)ah / 2;

    graph.TranslateTransform(tx, ty, MatrixOrderPrepend);
    graph.RotateTransform(m_rotate, MatrixOrderPrepend);
    graph.TranslateTransform(-ty, -tx, MatrixOrderPrepend);

    graph.DrawImage(m_image, dest, l, t, w, h, UnitPixel, NULL, NULL, NULL);

    graph.SetTransform(&trans);
}
